package aceim.protocol.snuk182.mrim;
import java.util.Arrays;
import java.util.List;
import aceim.api.IProtocol;
import aceim.api.dataentity.Buddy;
import aceim.api.dataentity.BuddyGroup;
import aceim.api.dataentity.ConnectionState;
import aceim.api.dataentity.FileMessage;
import aceim.api.dataentity.FileProgress;
import aceim.api.dataentity.ItemAction;
import aceim.api.dataentity.Message;
import aceim.api.dataentity.OnlineInfo;
import aceim.api.dataentity.ServiceMessage;
import aceim.api.dataentity.TextMessage;
import aceim.api.dataentity.tkv.TKV;
import aceim.api.service.AccountService;
import aceim.api.service.ApiConstants;
import aceim.api.service.ICoreProtocolCallback;
import aceim.api.service.ProtocolException;
import aceim.api.service.ProtocolException.Cause;
import aceim.api.utils.Logger;
import aceim.api.utils.Logger.LoggerLevel;
import aceim.api.utils.Utils;
import aceim.protocol.snuk182.mrim.inner.MrimConstants;
import aceim.protocol.snuk182.mrim.inner.MrimException;
import aceim.protocol.snuk182.mrim.inner.MrimServiceInternal;
import aceim.protocol.snuk182.mrim.inner.MrimServiceResponse;
import aceim.protocol.snuk182.mrim.inner.dataentity.MrimBuddy;
import aceim.protocol.snuk182.mrim.inner.dataentity.MrimFileTransfer;
import aceim.protocol.snuk182.mrim.inner.dataentity.MrimGroup;
import aceim.protocol.snuk182.mrim.inner.dataentity.MrimMessage;
import aceim.protocol.snuk182.mrim.inner.dataentity.MrimOnlineInfo;
import aceim.protocol.snuk182.mrim.utils.ProtocolUtils;
import aceim.protocol.snuk182.mrim.utils.ResourceUtils;
import android.content.Context;
public class MrimService extends AccountService {
public MrimService(byte serviceId, String protocolUid, ICoreProtocolCallback callback, Context context) {
super(serviceId, protocolUid, callback, context);
}
@Override
protected ConnectionState getCurrentState() {
return MrimEntityAdapter.mrimConnectionState2ConnectionState(internal.getCurrentState());
}
@Override
protected void keepaliveRequest() {
internal.askForWebAuthKey();
}
@Override
protected void timeoutReconnect() {
internal.getRunnableService().disconnect();
internal.connectInternal();
}
@Override
public IProtocol getProtocol() {
return protocol;
}
private final IProtocol protocol = new IProtocol(){
@Override
public void buddyAction(ItemAction arg0, Buddy arg1) {
// TODO Auto-generated method stub
}
@Override
public void buddyGroupAction(ItemAction arg0, BuddyGroup arg1) {
// TODO Auto-generated method stub
}
@Override
public void cancelFileFransfer(long messageId) {
try {
internal.request(MrimServiceInternal.REQ_FILECANCEL, messageId);
} catch (MrimException e) {
Logger.log(e);
getCoreService().notification(e.getLocalizedMessage());
}
}
@Override
public void connect(OnlineInfo arg0) {
sendKeepalive();
try {
connectInternal(arg0);
} catch (ProtocolException e) {
Logger.log(e);
getCoreService().notification(e.getLocalizedMessage());
}
}
@Override
public void disconnect() {
try {
internal.request(MrimServiceInternal.REQ_DISCONNECT);
} catch (MrimException e) {
Logger.log(e);
getCoreService().notification(e.getLocalizedMessage());
}
}
@Override
public void joinChatRoom(String arg0, boolean arg1) {}
@Override
public void leaveChatRoom(String arg0) {}
@Override
public void messageResponse(Message message, boolean accept) {
try {
if (message instanceof FileMessage) {
internal.request(MrimServiceInternal.REQ_FILERESPOND, message.getMessageId(), accept);
} else if (message instanceof ServiceMessage) {
if (message.getContactDetail().equals(getContext().getString(R.string.ask_authorization))) {
internal.request(MrimServiceInternal.REQ_AUTHRESPONSE, message.getContactUid(), accept);
}
}
} catch (MrimException e) {
Logger.log(e);
getCoreService().notification(e.getLocalizedMessage());
}
}
@Override
public void removeAccountPhoto() {}
@Override
public void requestFullInfo(String arg0, boolean shortInfo) {
try {
if (shortInfo){
internal.request(MrimServiceInternal.REQ_GETSHORTBUDDYINFO, arg0);
} else {
internal.request(MrimServiceInternal.REQ_GETFULLBUDDYINFO, arg0);
}
} catch (MrimException e) {
Logger.log(e);
getCoreService().notification(e.getLocalizedMessage());
}
}
@Override
public void requestIcon(String arg0) {
// TODO Auto-generated method stub
}
@Override
public long sendMessage(Message message) {
try {
Object result;
if (message instanceof TextMessage) {
MrimMessage mrimMessage = MrimEntityAdapter.textMessage2MrimMessage(getProtocolUid(), (TextMessage) message);
result = mrimMessage.messageId = ResourceUtils.RANDOM.nextInt();
internal.request(MrimServiceInternal.REQ_SENDMESSAGE, mrimMessage);
} else if (message instanceof FileMessage) {
result = ResourceUtils.RANDOM.nextInt();
internal.request(MrimServiceInternal.REQ_SENDFILE, message.getContactUid(), MrimEntityAdapter.getFilesFromFileMessage((FileMessage)message), (Integer)result);
} else {
result = null;
}
if (result instanceof Long) {
return (Long) result;
} else {
return 0;
}
} catch (MrimException e) {
Logger.log(e);
getCoreService().notification(e.getLocalizedMessage());
return 0;
}
}
@Override
public void sendTypingNotification(String recipient) {
try {
internal.request(MrimServiceInternal.REQ_SENDTYPING, recipient);
} catch (MrimException e) {
Logger.log(e);
getCoreService().notification(e.getLocalizedMessage());
}
}
@Override
public void setFeature(String featureId, OnlineInfo info) {
// This helps parsing Bundles
info.getFeatures().setClassLoader(TKV.class.getClassLoader());
try {
if (featureId.equals(ApiConstants.FEATURE_STATUS) || featureId.equals(ApiConstants.FEATURE_XSTATUS)) {
byte status = info.getFeatures().getByte(ApiConstants.FEATURE_STATUS, (byte) -1);
byte xstatus = info.getFeatures().getByte(ApiConstants.FEATURE_XSTATUS, (byte) -1);
boolean isChat = MrimApiConstants.STATUS_FREE4CHAT == status;
int mstatus = (isChat || (xstatus > -1)) ? MrimConstants.STATUS_OTHER : MrimEntityAdapter.userStatus2MrimUserStatus(status);
String mxstatus = isChat ? "STATUS_CHAT" : MrimEntityAdapter.userXStatus2MrimXStatus(xstatus);
internal.request(MrimServiceInternal.REQ_SETSTATUS, mstatus, mxstatus, info.getXstatusName(), info.getXstatusDescription());
} /*else if (featureId.equals(IcqApiConstants.FEATURE_BUDDY_VISIBILITY)) {
byte value = info.getFeatures().getByte(featureId, (byte) 0);
internal.request(ICQServiceInternal.REQ_BUDDYVISIBILITY, info.getProtocolUid(), value < 0 ? ICQConstants.VIS_REGULAR : ICQEntityAdapter.BUDDY_VISIBILITY_MAPPING[value]);
} */
} catch (MrimException e) {
Logger.log(e);
getCoreService().notification(e.getLocalizedMessage());
}
}
@Override
public void uploadAccountPhoto(String arg0) {}
};
private MrimServiceResponse mrimResponse = new MrimServiceResponse(){
@SuppressWarnings("unchecked")
@Override
public Object respond(short action, Object... args) {
switch (action) {
case MrimServiceResponse.RES_GET_FILE_FOR_SAVING:
return Utils.createLocalFileForReceiving((String) args[0], new Buddy((String) args[1], getProtocolUid(), ResourceUtils.PROTOCOL_NAME, getServiceId()), (Long) args[2]);
case MrimServiceResponse.RES_KEEPALIVE:
resetHeartbeat();
break;
case MrimServiceResponse.RES_LOG:
Logger.log((String)args[0], LoggerLevel.INFO);
break;
case MrimServiceResponse.RES_CONNECTED:
getCoreService().connectionStateChanged(ConnectionState.CONNECTED, -1);
break;
case MrimServiceResponse.RES_DISCONNECTED:
closeKeepaliveThread();
System.gc();
if (args.length > 0){
Logger.log((String) args[0], LoggerLevel.INFO);
getCoreService().connectionStateChanged(ConnectionState.DISCONNECTED, Cause.CONNECTION_ERROR.ordinal());
} else {
getCoreService().connectionStateChanged(ConnectionState.DISCONNECTED, -1);
}
break;
case MrimServiceResponse.RES_SAVEIMAGEFILE:
getCoreService().iconBitmap((String) args[1], (byte[]) args[0], (String) args[2]);
break;
case MrimServiceResponse.RES_CLUPDATED:
List<MrimBuddy> mrimBuddies = (List<MrimBuddy>) args[0];
List<MrimGroup> mrimGroups = (List<MrimGroup>) args[1];
getCoreService().buddyListUpdated(MrimEntityAdapter.mrimBuddyGroupList2BuddyGroupList(ResourceUtils.PROTOCOL_NAME, mrimGroups, internal.getMrid(), getServiceId(), mrimBuddies));
break;
case MrimServiceResponse.RES_MESSAGE:
TextMessage txtmessage = MrimEntityAdapter.mrimMessage2TextMessage((MrimMessage) args[0], getServiceId());
getCoreService().message(txtmessage);
break;
case MrimServiceResponse.RES_BUDDYSTATECHANGED:
OnlineInfo oi = MrimEntityAdapter.mrimOnlineInfo2OnlineInfo((MrimOnlineInfo) args[0], getServiceId());
getCoreService().buddyStateChanged(Arrays.asList(oi));
break;
case MrimServiceResponse.RES_CONNECTING:
getCoreService().connectionStateChanged(ConnectionState.CONNECTING, (Integer) args[0]);
break;
case MrimServiceResponse.RES_FILEMESSAGE:
getCoreService().message(MrimEntityAdapter.mrimFileTransferMessage2FileMessage((MrimFileTransfer) args[0], getServiceId()));
break;
case MrimServiceResponse.RES_NOTIFICATION:
getCoreService().notification((String) args[0]);
break;
case MrimServiceResponse.RES_ACCOUNTUPDATED:
getCoreService().accountStateChanged(MrimEntityAdapter.mrimOnlineInfo2OnlineInfo((MrimOnlineInfo) args[0], getServiceId()));
break;
case MrimServiceResponse.RES_AUTHREQUEST:
getCoreService().message(MrimEntityAdapter.authRequestToServiceMessage(getServiceId(), (String) args[0], (String) args[1], getContext()));
break;
case MrimServiceResponse.RES_FILEPROGRESS:
FileProgress fp = new FileProgress(getServiceId(), ProtocolUtils.bytes2LongBE((byte[]) args[0], 0), (String) args[1], (Long) args[2], (Long) args[3], (Boolean) args[4], (String) args[6], (String) args[5]);
getCoreService().fileProgress(fp);
break;
case MrimServiceResponse.RES_MESSAGEACK:
getCoreService().messageAck((String) args[0], (Long) args[1], MrimEntityAdapter.mrimMessageAck2MessageAck((Byte) args[2]));
break;
case MrimServiceResponse.RES_TYPING:
getCoreService().typingNotification((String) args[0]);
break;
}
return null;
}
};
private MrimServiceInternal internal = new MrimServiceInternal(mrimResponse);
private void connectInternal(OnlineInfo info) throws ProtocolException {
String username = getCoreService().requestPreference(ResourceUtils.KEY_USERNAME);
String password = getCoreService().requestPreference(ResourceUtils.KEY_PASSWORD);
String host = getCoreService().requestPreference(ResourceUtils.KEY_LOGIN_HOST);
String port = getCoreService().requestPreference(ResourceUtils.KEY_LOGIN_PORT);
String ping = getCoreService().requestPreference(ResourceUtils.KEY_PING_TIMEOUT);
if (ping != null){
try {
pingTimeout = Integer.parseInt(ping);
} catch (Exception e) {}
}
if (username == null || password == null){
throw new ProtocolException(Cause.BROKEN_AUTH_DATA);
}
int status = MrimEntityAdapter.userStatus2MrimUserStatus(info.getFeatures().getByte(ApiConstants.FEATURE_STATUS, (byte) -1));
int xstatus = MrimEntityAdapter.userStatus2MrimUserStatus(info.getFeatures().getByte(ApiConstants.FEATURE_XSTATUS, (byte) -1));
try {
internal.request(MrimServiceInternal.REQ_CONNECT, username, password, host, port, status, xstatus, info.getXstatusName(), info.getXstatusDescription());
} catch (MrimException e) {
Logger.log(e);
getCoreService().notification(e.getLocalizedMessage());
}
}
}